package com.example.myapplication.utils

import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast
import com.example.myapplication.LoginActivity
import com.example.myapplication.UserSession
import kotlinx.coroutines.CoroutineExceptionHandler
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.sql.SQLException

/**
 * 错误处理工具类
 */
object ErrorHandler {
    
    const val TAG = "ErrorHandler"
    
    /**
     * 错误级别
     */
    enum class ErrorLevel {
        INFO,    // 信息提示
        WARNING, // 警告
        ERROR,   // 错误
        FATAL    // 严重错误
    }
    
    /**
     * 用户友好的错误消息映射
     */
    private val friendlyMessages = mapOf(
        UnknownHostException::class.java to "网络连接失败，请检查网络设置",
        SocketTimeoutException::class.java to "连接超时，请重试",
        SQLException::class.java to "数据库操作失败，请重试",
        SecurityException::class.java to "权限不足，请联系管理员",
        IllegalArgumentException::class.java to "输入参数错误，请检查输入内容",
        IllegalStateException::class.java to "应用状态异常，请重启应用",
        OutOfMemoryError::class.java to "内存不足，请关闭其他应用后重试",
        NullPointerException::class.java to "数据异常，请重试或联系技术支持"
    )
    
    /**
     * 创建协程异常处理器
     */
    fun createCoroutineExceptionHandler(
        context: Context,
        tag: String = TAG,
        onError: ((Throwable) -> Unit)? = null
    ): CoroutineExceptionHandler {
        return CoroutineExceptionHandler { _, throwable ->
            handleError(context, throwable, tag)
            onError?.invoke(throwable)
        }
    }
    
    /**
     * 处理错误的主方法
     */
    fun handleError(
        context: Context,
        throwable: Throwable,
        tag: String = TAG,
        showToUser: Boolean = true
    ) {
        // 记录错误日志
        val level = getErrorLevel(throwable)
        val userMessage = getUserFriendlyMessage(throwable)
        
        logError(tag, throwable, level, userMessage)
        
        // 向用户显示友好提示
        if (showToUser) {
            showErrorToUser(context, throwable, level, userMessage)
        }
        
        // 特殊错误处理
        handleSpecialErrors(context, throwable)
    }
    
    /**
     * 获取错误级别
     */
    private fun getErrorLevel(throwable: Throwable): ErrorLevel {
        return when (throwable) {
            is OutOfMemoryError -> ErrorLevel.FATAL
            is SecurityException -> ErrorLevel.ERROR
            is SQLException -> ErrorLevel.ERROR
            is UnknownHostException, is SocketTimeoutException -> ErrorLevel.WARNING
            else -> ErrorLevel.ERROR
        }
    }
    
    /**
     * 获取用户友好消息
     */
    private fun getUserFriendlyMessage(throwable: Throwable): String {
        return friendlyMessages[throwable::class.java]
            ?: "操作失败: ${throwable.message ?: "未知错误"}"
    }
    
    /**
     * 记录错误日志
     */
    private fun logError(tag: String, throwable: Throwable, level: ErrorLevel, userMessage: String) {
        val logMessage = """
            错误级别: $level
            用户消息: $userMessage
            异常类型: ${throwable::class.java.simpleName}
            异常消息: ${throwable.message}
        """.trimIndent()
        
        when (level) {
            ErrorLevel.INFO -> Log.i(tag, logMessage, throwable)
            ErrorLevel.WARNING -> Log.w(tag, logMessage, throwable)
            ErrorLevel.ERROR -> Log.e(tag, logMessage, throwable)
            ErrorLevel.FATAL -> Log.wtf(tag, logMessage, throwable)
        }
    }
    
    /**
     * 向用户显示错误
     */
    private fun showErrorToUser(context: Context, throwable: Throwable, level: ErrorLevel, userMessage: String) {
        try {
            when (level) {
                ErrorLevel.INFO -> {
                    Toast.makeText(context, userMessage, Toast.LENGTH_SHORT).show()
                }
                ErrorLevel.WARNING -> {
                    Toast.makeText(context, userMessage, Toast.LENGTH_LONG).show()
                }
                ErrorLevel.ERROR, ErrorLevel.FATAL -> {
                    showErrorDialog(context, level, userMessage)
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "显示错误提示失败", e)
            // 降级为Toast
            Toast.makeText(context, userMessage, Toast.LENGTH_LONG).show()
        }
    }
    
    /**
     * 显示错误对话框
     */
    private fun showErrorDialog(context: Context, level: ErrorLevel, userMessage: String) {
        try {
            val title = when (level) {
                ErrorLevel.FATAL -> "严重错误"
                ErrorLevel.ERROR -> "操作失败"
                else -> "提示"
            }
            
            AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(userMessage)
                .setPositiveButton("确定") { dialog, _ -> dialog.dismiss() }
                .apply {
                    if (level == ErrorLevel.FATAL) {
                        setNegativeButton("重启应用") { _, _ ->
                            restartApp(context)
                        }
                    }
                }
                .show()
        } catch (e: Exception) {
            Log.e(TAG, "显示错误对话框失败", e)
            Toast.makeText(context, userMessage, Toast.LENGTH_LONG).show()
        }
    }
    
    /**
     * 处理特殊错误
     */
    private fun handleSpecialErrors(context: Context, throwable: Throwable) {
        when (throwable) {
            is OutOfMemoryError -> {
                try {
                    MemoryUtils.clearMemoryCache()
                    MemoryUtils.forceGC()
                } catch (e: Exception) {
                    Log.e(TAG, "清理内存失败", e)
                }
            }
            is SecurityException -> {
                if (throwable.message?.contains("permission", true) == true) {
                    handlePermissionError(context)
                }
            }
        }
    }
    
    /**
     * 处理权限错误
     */
    private fun handlePermissionError(context: Context) {
        try {
            AlertDialog.Builder(context)
                .setTitle("权限不足")
                .setMessage("您的权限可能已过期，是否重新登录？")
                .setPositiveButton("重新登录") { _, _ ->
                    logout(context)
                }
                .setNegativeButton("取消", null)
                .show()
        } catch (e: Exception) {
            Log.e(TAG, "显示权限错误对话框失败", e)
        }
    }
    
    /**
     * 退出登录
     */
    private fun logout(context: Context) {
        try {
            UserSession.currentUser = null
            val intent = Intent(context, LoginActivity::class.java)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            context.startActivity(intent)
            
            if (context is Activity) {
                context.finish()
            }
        } catch (e: Exception) {
            Log.e(TAG, "退出登录失败", e)
        }
    }
    
    /**
     * 重启应用
     */
    private fun restartApp(context: Context) {
        try {
            val packageManager = context.packageManager
            val intent = packageManager.getLaunchIntentForPackage(context.packageName)
            intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            intent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(intent)
            
            if (context is Activity) {
                context.finish()
            }
            
            System.exit(0)
        } catch (e: Exception) {
            Log.e(TAG, "重启应用失败", e)
        }
    }
    
    /**
     * 安全执行代码块
     */
    inline fun <T> safeExecute(
        context: Context,
        tag: String = TAG,
        defaultValue: T? = null,
        showError: Boolean = true,
        crossinline block: () -> T
    ): T? {
        return try {
            block()
        } catch (e: Exception) {
            if (showError) {
                handleError(context, e, tag)
            } else {
                Log.e(tag, "安全执行失败", e)
            }
            defaultValue
        }
    }
}

/**
 * 用户友好提示工具类
 */
object UserFeedback {
    
    /**
     * 显示成功消息
     */
    fun showSuccess(context: Context, message: String) {
        Toast.makeText(context, "✅ $message", Toast.LENGTH_SHORT).show()
    }
    
    /**
     * 显示警告消息
     */
    fun showWarning(context: Context, message: String) {
        Toast.makeText(context, "⚠️ $message", Toast.LENGTH_LONG).show()
    }
    
    /**
     * 显示信息消息
     */
    fun showInfo(context: Context, message: String) {
        Toast.makeText(context, "ℹ️ $message", Toast.LENGTH_SHORT).show()
    }
    
    /**
     * 显示加载提示
     */
    fun showLoading(context: Context, message: String = "加载中...") {
        Toast.makeText(context, "⏳ $message", Toast.LENGTH_SHORT).show()
    }
    
    /**
     * 显示确认对话框
     */
    fun showConfirmDialog(
        context: Context,
        title: String,
        message: String,
        onConfirm: () -> Unit,
        onCancel: (() -> Unit)? = null
    ) {
        try {
            AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("确定") { _, _ -> onConfirm() }
                .setNegativeButton("取消") { _, _ -> onCancel?.invoke() }
                .show()
        } catch (e: Exception) {
            Log.e("UserFeedback", "显示确认对话框失败", e)
        }
    }
}